<h2>Why is this an issue?</h2>
<p>When calling the <code>BeginInvoke</code> method of a <a href="https://learn.microsoft.com/en-us/dotnet/api/system.delegate">delegate</a>,
resources are allocated that are only freed up when <code>EndInvoke</code> is called. Failing to pair <code>BeginInvoke</code> with
<code>EndInvoke</code> can lead to <a href="https://en.wikipedia.org/wiki/Resource_leak">resource leaks</a> and incomplete asynchronous calls.</p>
<p>This rule raises an issue in the following scenarios:</p>
<ul>
  <li> The <code>BeginInvoke</code> method is called without any callback, and it is not paired with a call to <code>EndInvoke</code> in the same
  block. </li>
  <li> A callback with a single parameter of type <code>IAsyncResult</code> does not contain a call to <code>EndInvoke</code> in the same block. </li>
</ul>
<h2>How to fix it</h2>
<h3>Code examples</h3>
<h4>Noncompliant code example</h4>
<p><code>BeginInvoke</code> without callback:</p>
<pre data-diff-id="1" data-diff-type="noncompliant">
public delegate string AsyncMethodCaller();

public static void Main()
{
    AsyncExample asyncExample = new AsyncExample();
    AsyncMethodCaller caller = new AsyncMethodCaller(asyncExample.MyMethod);

    // Initiate the asynchronous call.
    IAsyncResult result = caller.BeginInvoke(null, null); // Noncompliant: not paired with EndInvoke
}
</pre>
<p><code>BeginInvoke</code> with callback:</p>
<pre data-diff-id="2" data-diff-type="noncompliant">
public delegate string AsyncMethodCaller();

public static void Main()
{
    AsyncExample asyncExample = new AsyncExample();
    AsyncMethodCaller caller = new AsyncMethodCaller(asyncExample.MyMethod);

    IAsyncResult result = caller.BeginInvoke(
        new AsyncCallback((IAsyncResult ar) =&gt; {}),
        null); // Noncompliant: not paired with EndInvoke
}
</pre>
<h4>Compliant solution</h4>
<p><code>BeginInvoke</code> without callback:</p>
<pre data-diff-id="1" data-diff-type="compliant">
public delegate string AsyncMethodCaller();

public static void Main()
{
    AsyncExample asyncExample = new AsyncExample();
    AsyncMethodCaller caller = new AsyncMethodCaller(asyncExample.MyMethod);

    IAsyncResult result = caller.BeginInvoke(null, null);

    string returnValue = caller.EndInvoke(result);
}
</pre>
<p><code>BeginInvoke</code> with callback:</p>
<pre data-diff-id="2" data-diff-type="compliant">
public delegate string AsyncMethodCaller();

public static void Main()
{
    AsyncExample asyncExample = new AsyncExample();
    AsyncMethodCaller caller = new AsyncMethodCaller(asyncExample.MyMethod);

    IAsyncResult result = caller.BeginInvoke(
        new AsyncCallback((IAsyncResult ar) =&gt;
            {
                // Call EndInvoke to retrieve the results.
                string returnValue = caller.EndInvoke(ar);
            }), null);
}
</pre>
<h2>Resources</h2>
<h3>Documentation</h3>
<ul>
  <li> <a
  href="https://learn.microsoft.com/en-us/dotnet/standard/asynchronous-programming-patterns/calling-synchronous-methods-asynchronously">Calling
  Synchronous Methods Asynchronously</a> </li>
  <li> <a
  href="https://learn.microsoft.com/en-us/dotnet/standard/asynchronous-programming-patterns/asynchronous-programming-using-delegates">Asynchronous
  Programming Using Delegates</a> </li>
  <li> <a href="https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.control.begininvoke">BeginInvoke()</a> </li>
  <li> <a href="https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.control.endinvoke">EndInvoke()</a> </li>
  <li> <a href="https://learn.microsoft.com/en-us/dotnet/api/system.asynccallback">AsyncCallback Delegate</a> </li>
</ul>

